<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
function get_uuid(){
    static $uuid = '';
    $uid = uniqid("", true);
    $data = time().$_SERVER['REQUEST_TIME'].$_SERVER['REMOTE_ADDR'].rand(1111,9999);
    $uuid = strtoupper(hash('ripemd128',$uid.$uuid.md5($data)));
    return $uuid;
}
/**
 * 密码加密
 */
function encrypt_password($password){
    return md5(md5($password) . md5('#huisanjiang2017#'));
}

/**
 * 数据签名
 * @param array $data 被认证的数据
 * @return string 签名
 */
function data_signature($data = [])
{
    if(!is_array($data)){
        $data = (array)$data;
    }
    ksort($data);
    $code = http_build_query($data);
    $sign = sha1($code);
    return $sign;
}

/**
 * 返回按层级加前缀的菜单数组
 * @author  rainfer
 * @param array|mixed $menu 待处理菜单数组
 * @param string $id_field 主键id字段名
 * @param string $pid_field 父级字段名
 * @param string $lefthtml 前缀
 * @param int $pid 父级id
 * @param int $lvl 当前lv
 * @param int $leftpin 左侧距离
 * @return array
 */
function menu_left($menu,$id_field='id',$pid_field='pid',$lefthtml = '─' , $pid=0 , $lvl=0, $leftpin=0)
{
    $arr=array();
    foreach ($menu as $v){
        if($v[$pid_field]==$pid){
            $v['lvl']=$lvl + 1;
            $v['leftpin']=$leftpin;
            $v['lefthtml']='├'.str_repeat($lefthtml,$lvl);
            $arr[]=$v;
            $arr= array_merge($arr,menu_left($menu,$id_field,$pid_field,$lefthtml,$v[$id_field], $lvl+1 ,$leftpin+20));
        }
    }
    return $arr;
}

/**
 * 是否存在控制器
 * @param string $module 模块
 * @param string $controller 待判定控制器名
 * @return boolean
 */
function has_controller($module,$controller)
{
    $arr=ReadClass::readDir(APP_PATH . $module. DS .'controller');
    if((!empty($arr[$controller])) && $arr[$controller]['class_name']==$controller){
        return true;
    }else{
        return false;
    }
}

/**
 * 是否存在方法
 * @param string $module 模块
 * @param string $controller 待判定控制器名
 * @param string $action 待判定控制器名
 * @return number 方法结果，0不存在控制器 1存在控制器但是不存在方法 2存在控制和方法
 */
function has_action($module,$controller,$action)
{
    $arr= ReadClass::readDir(APP_PATH . $module. DS .'controller');
    if((!empty($arr[$controller])) && $arr[$controller]['class_name']==$controller ){
        $method_name=array_map('array_shift',$arr[$controller]['method']);
        if(in_array($action, $method_name)){
            return 2;
        }else{
            return 1;
        }
    }else{
        return 0;
    }
}

/**
 * @desc 获取IP
 */
function getIPaddress() {
    $IPaddress = '';
    if (isset($_SERVER)) {
        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $IPaddress = $_SERVER["HTTP_X_FORWARDED_FOR"];
        } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
            $IPaddress = $_SERVER["HTTP_CLIENT_IP"];
        } else {
            $IPaddress = $_SERVER["REMOTE_ADDR"];
        }
    } else {
        if (getenv("HTTP_X_FORWARDED_FOR")) {
            $IPaddress = getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("HTTP_CLIENT_IP")) {
            $IPaddress = getenv("HTTP_CLIENT_IP");
        } else {
            $IPaddress = getenv("REMOTE_ADDR");
        }
    }
    return $IPaddress;
}

/**
 * 格式化返回数据
 * @param $code -返回码
 * @param $data -返回数据集
 * @param string $msg
 * 返回描述信息
 * @return array
 */
function api_return($code, $data = [], $msg = 'SUCCESS')
{
    return ['code' => $code, 'data' => $data, 'msg' => $msg];
}

// 添加接口请求日志
function add_interface_request_log($params, $action, $member_ip = '', $param)
{
    if (!$member_ip){
        return ['data' => 'add_interface_request_log','code' => 400015,'msg' => config('error_code.400015')];
    }
    $log['interface'] = $action;
    $log['request_time'] = time();
    $log['member_ip'] = $member_ip;
    $log['data'] = json_encode($param);
    if (isset($params['member_id']))
        $log['member_id'] = $params['member_id'];
    $rs = db('interface_request_log')->insert($log);
    if (!$rs){
        return ['code'=>400016,'msg'=>config('error_code.400016')];
    }else{
       return ['code' => 200,'msg' => 'SUCCESS'];
    }
}

// 验证短信验证码  3分钟有效
// $code 验证码
// $phone 手机号码
// $type 短信类型 1、登录；2、找回密码；
function check_send_code($code, $phone, $type)
{
    $where = ['code' => $code, 'phone' => $phone, 'type' => $type];
    $code = db('note_code')->where($where)->order('id desc')->find();
    if (!$code)
        return ['data' => '', 'code' => 400007, 'msg' => '验证码不存在'];
    if ($code['status'] > 0)
        return ['data' => '', 'code' => 400018, 'msg' => '验证码已使用'];
    if ($code['add_time'] < (time() - 180))
        return ['data' => '', 'code' => 400019, 'msg' => '验证码已过期'];

    // 将验证码状态改为已使用
    db('note_code')->where($where)->update(['status' => 1]);

    return ['data' => '', 'code' => 200, 'msg' => 'SUCCESS'];
}

/**
 *获取完整的图片路径
 * @param string $img
 * @return string
 */
function get_img_url($img = '', $default = '')
{
    if (!$img) { // 没有图片使用默认图
        if ($default == 'headimgurl') { // 默认头像
            $img = config('image_host') . '/uploads/logo/default_head.png';
        } else if ($default == 'logo') { // 默认Logo
            $img = config('image_host')  . '/static/home/images/shop_logo_03.jpg';
        } else { // 默认图
            $img = config('image_host')  . '/static/home/images/shop2_03.jpg';
        }
    } else {
        if (!preg_match('/^((https|http)?:\/\/)[^\s]+/i', $img)) // 有图片检查是否有http://
        {
            $img = config('image_host') . '/' . $img; // 没有就拼装图片地址域名
        }
    }
    return $img;
}

/**
 *
 */
//参数1：访问的URL，参数2：post数据(不填则为GET)，参数3：提交的$cookies,参数4：是否返回$cookies
function curl_request($url,$post='',$cookie='', $returnCookie=0){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
    curl_setopt($curl, CURLOPT_REFERER, "http://XXX");
    if($post) {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
    }
    if($cookie) {
        curl_setopt($curl, CURLOPT_COOKIE, $cookie);
    }
    curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
    curl_setopt($curl, CURLOPT_TIMEOUT, 10);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    if (curl_errno($curl)) {
        return curl_error($curl);
    }
    curl_close($curl);
    if($returnCookie){
        list($header, $body) = explode("\r\n\r\n", $data, 2);
        preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
        $info['cookie']  = substr($matches[1][0], 1);
        $info['content'] = $body;
        return $info;
    }else{
        $output_array = json_decode($data,true);
        return $output_array;
    }
}

/**
 *  post提交数据
 * @param  string $url 请求Url
 * @param  array $datas 提交的数据
 * @return url响应返回的html
 */
function sendPost($url, $datas) {
    $temps = array();
    foreach ($datas as $key => $value) {
        $temps[] = sprintf('%s=%s', $key, $value);
    }
    $post_data = implode('&', $temps);
    $url_info = parse_url($url);
    if(empty($url_info['port']))
    {
        $url_info['port']=80;
    }
    $httpheader = "POST " . $url_info['path'] . " HTTP/1.0\r\n";
    $httpheader.= "Host:" . $url_info['host'] . "\r\n";
    $httpheader.= "Content-Type:application/x-www-form-urlencoded\r\n";
    $httpheader.= "Content-Length:" . strlen($post_data) . "\r\n";
    $httpheader.= "Connection:close\r\n\r\n";
    $httpheader.= $post_data;
    $fd = fsockopen($url_info['host'], $url_info['port']);
    fwrite($fd, $httpheader);
    $gets = "";
    $headerFlag = true;
    while (!feof($fd)) {
        if (($header = @fgets($fd)) && ($header == "\r\n" || $header == "\n")) {
            break;
        }
    }
    while (!feof($fd)) {
        $gets.= fread($fd, 128);
    }
    fclose($fd);

    return $gets;
}


// 获取半径范围内的经纬度
// $lat 纬度
// $lon 经度
// $raidus 半径米
function getAround($lat, $lon, $radius)
{
    $PI = 3.14159265;
    $latitude = $lat;
    $longitude = $lon;

    $degree = (24901 * 1609) / 360.0;
    $radiusMile = $radius;

    $dpmLat = 1 / $degree;
    $radiusLat = $dpmLat * $radiusMile;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;

    $mpdLng = $degree * cos($latitude * ($PI / 180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng * $radiusMile;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return [$minLat, $maxLat, $minLng, $maxLng];
}

/**
 *对象转数组
 */
function object_array($array) {
    if(is_object($array)) {
        $array = (array)$array;
    }
    if(is_array($array)) {
        foreach($array as $key=>$value) {
            $array[$key] = object_array($value);
        }
    }
    return $array;
}

//日期转Unix时间戳
function date_to_unixtime($date, $timezone = 'PRC') {
    $datetime= new DateTime($date, new DateTimeZone($timezone));
    return $datetime->format('U');
}
//Unix时间戳转日期
function unixtime_to_date($unixtime, $timezone = 'PRC') {
    $datetime = new DateTime("@$unixtime"); //DateTime类的bug，加入@可以将Unix时间戳作为参数传入
    $datetime->setTimezone(new DateTimeZone($timezone));
    return $datetime->format("Y-m-d");
}

/**
 * 通过IP获取对应城市信息(该功能基于淘宝第三方IP库接口)
 * @param $ip IP地址,如果不填写，则为当前客户端IP
 * @return  如果成功，则返回数组信息，否则返回false
 */
function getIpInfo(){
    $ip=getIPaddress();  //get_client_ip()为tp自带函数，如没有，自己百度搜索。此处就不重复复制了
    $url='http://ip.taobao.com/service/getIpInfo.php?ip='.$ip;
    $result = file_get_contents($url);
    $result = json_decode($result,true);
    if($result['code']!==0 || !is_array($result['data'])) return false;
    return $result['data'];
}

/**
 * 淘宝刷新授权
 */
function tbrefresh($param)
{
    $postfields = array('grant_type' => 'authorization_code',
        'client_id' => '24635648',
        'client_secret' => 'e3c6f335ca39011870018a730503de72',
        'grant_type' => $param['refresh_token'],
        'state' => '1212',
        'view' => 'web');
    $url = 'https://oauth.taobao.com/token';
    $post_data = '';
    foreach ($postfields as $key => $value) {
        $post_data .= "$key=" . urlencode($value) . "&";
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

    //指定post数据
    curl_setopt($ch, CURLOPT_POST, true);

    //添加变量
    curl_setopt($ch, CURLOPT_POSTFIELDS, substr($post_data, 0, -1));
    $output = curl_exec($ch);
    $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($httpStatusCode == 200) {
        $info = json_decode($output, true);
        $info['token_endtime'] = $info['expires_in'] +time(); // 过期时间
        $info['w1_expires_in'] = time()+$info['w1_expires_in']; // w1级别API或字段的访问过期时间
        $info['refresh_token_valid_time'] = floor($info['refresh_token_valid_time'] / 1000); // 授权过期时间一个月
        $info['re_expires_in'] = $info['re_expires_in']+time(); // 刷新授权剩余的过期时间 与$info['refresh_token_valid_time'] 相同
        $info['expires_in'] = floor($info['expires_in'] / 1000); // token过期时间（24h）
        $info['w1_valid'] = floor($info["w1_valid"] / 1000);
        $info['w2_valid'] = floor($info["w2_valid"] / 1000);
        $info['r1_expires_in'] = $info["r1_expires_in"]+time(); //r1级别API或字段的访问过期时间
        $info['r2_expires_in'] = $info["r2_expires_in"]+time(); //r2级别API或字段的访问过期时间
        $info['r2_valid'] = floor($info["r2_valid"] / 1000);
        $info['r1_valid'] = floor($info["r1_valid"] / 1000);
        $auth_info = db('tbauth')->where(['taobao_user_id' => $param['taobao_user_id']])->find();
        if (!empty($auth_info)) {
            $info['id'] = $param['id'];
            $flag = db('tbauth')->update($info);
        } else {
            $flag = db('tbauth')->insert($info);
        }
        if ($flag) {
            return ['code'=>200,'msg'=>'success','data'=>$info['access_token']];
        } else {
            return ['code'=>0,'msg'=>'更新失败','data'=>''];
        }
    }else{
        return ['code'=>0,'msg'=>$httpStatusCode,'data'=>''];
    }
}

/**
 * @param $list
 * @param string $pk
 * @param string $pid
 * @param string $child
 * @param int $root
 */
function make_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    $tree = array();
    $packData = array();
    //转换数组的结构
    foreach ($list as $data) {
        $packData[$data[$pk]] = $data;
    }
    foreach ($packData as $key => $val) {
        if ($val[$pid] == $root) {//代表跟节点
            $tree[] =& $packData[$key];
        } else {
    //找到其父类
            $packData[$val[$pid]][$child][] =& $packData[$key];
        }
    }
    return $tree;
}

if (!function_exists('send_post')) {
    /**
     * 发送post请求
     * @param string $url 请求地址
     * @param array $post_data post键值对数据
     * @return string
     */
    function send_post($url, $post_data) {

        $postdata = http_build_query($post_data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $postdata,
                'timeout' => 15 * 60 // 超时时间（单位:s）
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);

        return $result;
    }
}

if (!function_exists('httpRequest')) {
    /**
     * CURL请求
     * @param $url 请求url地址
     * @param $method 请求方法 get post
     * @param null $postfields post数据数组
     * @param array $headers 请求header信息
     * @param bool|false $debug  调试开启 默认false
     * @return mixed
     */
    function httpRequest($url, $method, $postfields = null, $headers = array(), $debug = false) {
        $method = strtoupper($method);
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间，如果设置为0，则无限等待 */
        curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        switch ($method) {
            case "POST":
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
                }
                break;
            default:
                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
                break;
        }
        $ssl = preg_match('/^https:\/\//i',$url) ? TRUE : FALSE;
        curl_setopt($ci, CURLOPT_URL, $url);
        if($ssl){
            curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
        }
        //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
        curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量，这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);
        /*curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
        $response = curl_exec($ci);
        $requestinfo = curl_getinfo($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);
            echo "=====info===== \r\n";
            print_r($requestinfo);
            echo "=====response=====\r\n";
            print_r($response);
        }
        curl_close($ci);
        return $response;
        //return array($http_code, $response,$requestinfo);
    }
}

